﻿
/*
SP webservice query reader May 2010 (c) by Paul KbWorks
Version 1.0.0.0
*/
//namespace KbWorks
KbWorks = {
    //begin className filterfunctions
    filterfunctions:
    {

        //adds a filter
        //begin function filteradd
        filteradd: function(columnname, fieldtype, elementname, operator, fieldinputtype) {
            if (this.filters == null) {
                this.filters = new Array;
            }
            var filternumber = this.filters.length;
            switch (fieldinputtype) {
                case "textbox":
                    {
                        this.filters[filternumber] = [columnname, fieldtype, document.getElementById(elementname).value, operator];
                        break;
                    }
                case "listbox":
                    {
                        var k = 0;
                        var alternatevalue = new Array;
                        var canhavealternatevalue = false;
                        var hasalternatevalue = false;
                        for (var j = 0; j < document.getElementById(elementname).length; j++) {

                            if (document.getElementById(elementname)[j].selected) {

                                if (canhavealternatevalue) {
                                    alternatevalue[k] = document.getElementById(elementname)[j].value;
                                    hasalternatevalue = true;
                                    k++;
                                }
                                else {
                                    this.filters[filternumber] = [columnname, fieldtype, document.getElementById(elementname)[j].value, operator];
                                    canhavealternatevalue = true;
                                }

                            }
                        }
                        if (hasalternatevalue) {
                            this.filters[filternumber][4] = alternatevalue;
                        }
                        break;
                    }
                default:
                    {
                        this.filters[filternumber] = [columnname, fieldtype, fieldinputtype, operator];
                        break;
                        break;
                    }

            }
            return this.filters;
        },
        //end function filteradd
        //
        //begin function deletelistboxfilter
        deletelistboxfilter: function() {
            this.divname
            for (var j = 0; j < document.getElementById(this.divname).length; j++) {
                if (document.getElementById(this.divname)[j].selected == true) {
                    document.getElementById(this.divname)[j].selected = false;
                }
            }

        }
        //end function deletelistboxfilter

    },
    //end className 
    //
    //begin className lists
    lists: {


        //
        //begin function searchitems
        searchitems: function(listToSearch) {
            // container for retrieved data
            var elt = document.getElementById(this.divname);
            try {
                var camlquery = "";
                var camlqueryafterfilterempty = false;
                var camlviewfields = "";

                if (this.WithoutFilters) {
                    camlquery = "";
                    camlqueryafterfilternotempty = true;
                }
                else {
                    camlquery = KbWorks.camlquerybuilder.generatequery(KbWorks.filterfunctions.filters);
                    if (camlquery == "") {
                        camlqueryafterfilternotempty = false;
                    }
                    else {
                        camlqueryafterfilternotempty = true;
                    }
                }
                camlviewfields = KbWorks.camlquerybuilder.generateviewfields(this.viewfields);
                if (camlqueryafterfilternotempty) {
                    $().SPServices({
                        operation: "GetListItems",
                        async: false,
                        webURL: this.weburl,
                        listName: listToSearch,
                        CAMLViewFields: camlviewfields,
                        CAMLQuery: camlquery,
                        completefunc: this._processresult
                    });
                }

            } catch (err) {
                KbWorks.UI._handleexception(elt, "Error: failed to load resource.");
            }
        },
        //end function searchitems
        //
        //begin function processresulkt
        _processresult: function(xData, status) {
            if (status == "error") {
                var elt = document.getElementById(KbWorks.lists.divname);
                KbWorks.UI._handleexception(elt, xData.responseText);
                return;
            }

            var ifield = 0;
            var fieldcount = 0;
            KbWorks.lists.fields = new Array;
            // process all fields
            jQuery(xData.responseXML).find("z\\:row").each(function() {
                var itemfields = new Array;
                for (var i = 0; i < KbWorks.lists.viewfields.length; i++) {

                    //check if there is another columnname like Title
                    if (KbWorks.lists.viewfields[i][3] != null) {
                        var owsfieldname = "ows_" + KbWorks.lists.viewfields[i][3]
                    }
                    else {
                        var owsfieldname = "ows_" + KbWorks.lists.viewfields[i][0]
                    }
                    if (KbWorks.lists.viewfields[i][2] != null) {
                        itemfields[i] = [KbWorks.lists.viewfields[i][1], $(this).attr(owsfieldname), KbWorks.lists.viewfields[i][2]];
                    }
                    else {

                        itemfields[i] = [KbWorks.lists.viewfields[i][1], $(this).attr(owsfieldname)];
                    }
                }

                KbWorks.lists.fields[fieldcount] = itemfields;
                fieldcount++;
            });
            KbWorks.lists.Fields = KbWorks.lists.fields;
            var elt = "";
            if (KbWorks.lists.WithoutFilters == false) {
                if (KbWorks.lists.searchbox) {
                    KbWorks.UI.searchbox(KbWorks.lists.fields);
                }
                else {

                    elt = document.getElementById(KbWorks.lists.divname);

                    KbWorks.UI.displaytable(elt, KbWorks.lists.fields);
                }
            }
            else {
                if (KbWorks.lists.divname == "FAQFeature") {
                    elt = document.getElementById(KbWorks.lists.divname);
                    KbWorks.UI.displayFAQ(elt, KbWorks.lists.fields);
                }
                else {

                    KbWorks.UI.searchbox(KbWorks.lists.fields);
                }
            }

        },
        //endfunction processresults,
        //
        //begin function add/update items
        insertitem: function(fields, weburl, listToAdd) {
            this.BR = "<br />";
            this.CRLF = String.fromCharCode(13, 10);
            this.reCRLF = new RegExp(this.CRLF, 'gi');
            this.returnID = "";
            // container for retrieved data
            var elt = document.getElementById(this.divname);
            try {
                // display loading
                //_displayloading(elt);
                var _id;
                var camloperation = "";
                var camlInsert = "";
                var newitem = "true";
                for (i = 0; i < fields.length; i++) {
                    var fieldvalue = fields[i][1].replace(this.reCRLF, this.BR);
                    camlInsert += "<Field Name='" + fields[i][0] + "' Type='" + fields[i][2] + "'>" + this._escapehtml(fieldvalue) + "</Field>";
                    if (fields[i][0] == "ID") {
                        var newitem = "false";
                    }
                }
                if (newitem == "true") {
                    camloperation = "<Batch OnError='Continue' ><Method ID='1' Cmd='New' >";
                }
                else {
                    camloperation = "<Batch OnError='Continue' ><Method ID='1' Cmd='Update' >";
                }
                camloperation += camlInsert;
                camloperation += "</Method></Batch>";
                $().SPServices({
                    operation: "UpdateListItems",
                    async: false,
                    webURL: weburl,
                    listName: listToAdd,
                    updates: camloperation,
                    completefunc: this._processupdate
                });
            } catch (err) {
                _handleexception(elt, "Error: failed to load resource.");
            }
        },
        //end function add/update items
        //
        //begin function _processupdate items
        _processupdate: function(xData, status) {
            var returnID;
            if (status == "error") {
                var elt = document.getElementById(this.divname);
                KbWorks.UI._handleexception(elt, xData.responseText);
                return;
            }
            var elt = document.getElementById("this.divname");
            // alert(xData.responseText);
            jQuery(xData.responseXML).find("z\\:row").each(function() {
                returnID = $(this).attr("ows_ID");
            });
            KbWorks.lists.returnedID = returnID;
        },
        //end function _processupdate items
        //
        //begin function _escapehtml items
        _escapehtml: function(str) {
            var div = document.createElement("div");
            var text = document.createTextNode(str);
            div.appendChild(text);
            return div.innerHTML;
        }

    },
    //end className lists
    //
    //begin className Display
    UI:
    {
        //functiondisplaysearchbox
        searchbox: function(fields) {
            var elt = document.getElementById(KbWorks.lists.elementtofill);
            var KbWorksHtml = "";
            if (KbWorks.lists.Getvalue) {
                fields.sort();

                //elt.innerHTML = fields[i][0][1];
                var highestnumber = fields.length - 1;

                elt.innerText = fields[highestnumber][0][1];
            }
            else {
                for (var i = 0; i < fields.length; i++) {
                    var opt = document.createElement("option");
                    opt.text = fields[i][0][1];
                    opt.value = fields[i][0][1];
                    elt.options.add(opt);

                }
            }

        },
        //end function searchbox
        //
        //begin function displayfeature
        displaytable: function(elt, fields) {
            // displays data: <fields> contains items with fields:
            // - SectionOrder, Section, QuestionOrder, Question, Answer (required)
            // - TopOrder (optional)
            var oData = document.createElement("div");
            //    oData.setAttribute("className", "data");

            // append main header
            var oHeader = document.createElement("H1");
            oHeader.innerHTML = "SearchResult";
            //oHeader.setAttribute("className", "data");
            oData.appendChild(oHeader);


            // create sections TOC
            var oFeature = document.createElement("div");
            //    oFeature.setAttribute("className", "feature");


            var table = document.createElement("table");
            table.setAttribute("className", "KbWorkstable");
            var tbody1 = document.createElement("TBODY");
            var i = 0;

            for (var i = 0; i < fields.length; i++) {
                // add columns
                if (i == 0) {
                    var tr = document.createElement("tr");

                    for (var k = 0; k < fields[i].length; k++) {
                        var th = document.createElement("th");
                        th.innerHTML = fields[i][k][0] + " <a href='' onclick='KbWorks.UI.sorttable(this);return false'><img className='KbWorksimg' alt='sorttable/reverse' src='/Style%20Library/Images/sort_up_down.png' /></a>";
                        th.setAttribute("className", "KbWorksthtd");
                        tr.appendChild(th);
                    }
                    j = 0;
                    tr.setAttribute("className", "KbWorksth");
                    tbody1.appendChild(tr);
                    table.appendChild(tbody1);
                    var tbody = document.createElement("TBODY");
                }
                var tr = document.createElement("tr");
                //for each field in row

                for (var j = 0; j < fields[i].length; j++) {
                    var td = document.createElement("td");

                    var tdvalue = fields[i][j][1];

                    if (tdvalue != null) {
                        if (tdvalue.substring(0, 4) == "http") {
                            tdvalue = tdvalue.substring(0, tdvalue.indexOf(","));
                            var oRef = document.createElement("a");
                            oRef.setAttribute("href", tdvalue);
                            oRef.innerText = fields[i][j][2];
                            td.appendChild(oRef);

                        }
                        else {
                            if (tdvalue.indexOf("#") > 0) {
                                tdvalue = tdvalue.substring(tdvalue.indexOf("#") + 1);
                            }

                            td.innerHTML = tdvalue;
                        }
                    }
                    td.setAttribute("className", "KbWorkstd");

                    tr.appendChild(td);

                }

                tbody.appendChild(tr);
            }
            if (tbody != null) {
                table.appendChild(tbody);
            }
            oFeature.appendChild(table);
            oData.appendChild(oFeature);

            // delete current content from <elt>
            KbWorks.UI._resetcontainer(elt);

            // append DOM content to <elt>
            elt.appendChild(oData);

            // alert(elt.innerHTML);

            //elt.innerHTML = a;
        },
        //end function displayfeature
        //
        //begin function resetcontainer
        _resetcontainer: function(elt) {
            // deletes current content from <elt>
            if (elt != null) {
                for (var i = 0; i < elt.children.length; i++) {
                    var oChild = elt.children(i);
                    // if (oChild.className == "data")
                    elt.removeChild(oChild);
                }
            }
        },
        //end function resetcontainer
        //
        //begin function display error
        _handleexception: function(elt, Err) {
            // displays error
            var oData = document.createElement("div");
            oData.setAttribute("className", "data");

            var oImg = document.createElement("img");
            oImg.setAttribute("src", "/Style%20Library/Images/warning16x16.gif"); //"http://hr.m2s.intranet/Style%20Library/Images/warning16x16.gif");
            oImg.width = 16;
            oImg.height = 16;
            oImg.setAttribute("title", "loading failed");
            oData.appendChild(oImg);

            var CRLF = String.fromCharCode(13, 10);
            var re = new RegExp(CRLF, 'gi');
            var txt = "Loading failed due the following error.";
            var oText = document.createElement("div");
            oText.innerHTML = txt;
            oData.appendChild(oText);

            txt = (Err.reason) ? Err.reason.replace(re, '<br />') + "<br />" +
        "Address: <a href='" + Err.url + "' target=_blank>" + Err.url + "</a>" : Err;
            oText = document.createElement("div");
            oText.innerHTML = txt;
            oData.appendChild(oText);

            // delete current content from <elt>
            KbWorks.UI._resetcontainer(elt);

            // append error to <elt>
            elt.appendChild(oData);
        },
        //end function display error
        //
        //begin funciton _displayloading
        _displayloading: function(elt) {
            // displays loading info
            var loading = document.createElement("div");
            loading.setAttribute("className", "data");
            var oImg = document.createElement("img");
            oImg.setAttribute("src", "/Style%20Library/Images/loading32x32.gif"); //"http://hr.m2s.intranet/Style%20Library/Images/loading32x32.gif");
            oImg.width = 32;
            oImg.height = 32;
            oImg.setAttribute("title", "loading ...");
            loading.appendChild(oImg);

            // delete current content from <elt>
            KbWorks.UI._resetcontainer(elt);

            // append loading info to <elt>
            elt.appendChild(loading);
        },
        //end funciton _displayloading
        //
        //Begin function Sort
        sorttable: function(w) {
            var table = KbWorks.UI._findparenttable(w);
            if (table == null) {
                return;
            }
            var groups = table.getElementsByTagName('tbody');
            // alert("group:" + groups.length);
            //  for (var i = 0; i < groups.length; i++) {
          
            KbWorks.UI._sortrows(groups[groups.length - 1], w.parentNode.cellIndex);
            //}
        },
        //end function Sort
        //
        //Begin function _findparenttable
        _findparenttable: function(el) {
            while (el.parentNode.nodeName.toLowerCase() != 'table' && el.parentNode.nodeName.toLowerCase() != 'body') {
                el = el.parentNode;
            }

            if (el.parentNode.nodeName.toLowerCase() != 'table') {
                return null;
            }
            else {
                return el.parentNode;
            }
        },
        //end function _findparenttable
        //
        //begin function _sortrows
        _sortrows: function(group, col) {

            var oRows = new Array(); //set the rows to be removed as an array of cloneNodes
            var iRows = new Array(); //set those rows' indexes as array

            for (var i = 0; i < group.rows.length; i++) {
                oRows[i] = group.rows[i].cloneNode(true);
                iRows[i] = group.rows[i].sectionRowIndex;
            }
            var oCol = new Array(); //set the string content of column cells as array
            var vCol = new Array(); //set the "compare" array for a future sorttable/reverse
            var Numeric = false;
           
            for (i = 0; i < iRows.length; i++) {
                if (group.rows[i].cells[col].innerHTML != "") {

                                                            if (!isNaN(group.rows[i].cells[col].innerHTML)) {
                                                                Numeric = true;
                                                            }
                    vCol[i] = oCol[i] = [group.rows[i].cells[col].firstChild.nodeValue, iRows[i]];
                }
            }

            if (Numeric == true) {
                oCol.sort(KbWorks.UI._sortnumber);
            }
            else {
                oCol.sort(); //sorts the content array
            }
            if (vCol.toString() == oCol.toString()) {
                oCol.reverse(); //if the content was already sorted, reverse
            }

            for (i = 0; i < group.rows.length; i++) {
                if (oCol[i] != null) {
                    group.replaceChild(oRows[oCol[i][1]], group.rows[i]); //writes the rows in a sorted/reversed order
                }
            }

        },
        //end function _sortrows
        //
        //begin function sortnumber
        _sortnumber: function(a, b) {
            return (parseInt(b) - parseInt(a));
        },
        //end function sortnumber
        //
        //begin function responsetext
        responsetext: function(elt, txt) {
            KbWorks.UI._resetcontainer(elt);
            var oText = document.createElement("div");
            oText.innerHTML = txt;
            elt.appendChild(oText);
        },
        //end function responsetext
        //
        //begin display FAQ
        displayFAQ: function(elt, fields) {
            // displays data: <fields> contains items with fields:
            // - SectionOrder, Section, QuestionOrder, Question, Answer (required)
            // - TopOrder (optional)

            // (default) sort (lexicographically) on first field, second field, etcetera
            fields.sort();

            // FAQ Feature
            var oData = document.createElement("div");
            oData.setAttribute("className", "column maincontent");

            // append main header
            var oHeader = document.createElement("H1");
            oHeader.innerHTML = "FAQ";
            oData.appendChild(oHeader);

            // create sections TOC
            var oFeature = document.createElement("div");
            oFeature.setAttribute("className", "feature");

            // append sections TOC header
            oHeader = document.createElement("H3");
            oHeader.innerHTML = "I have a question about";
            oFeature.appendChild(oHeader);

            // - collect top FAQs
            // - get sections info: count, titles (Section), id's (SectionOrder)
            // TODO (robustness): use id's (SectionOrder) only for (lexicographical) sorting and enumerate sections TOC links automatically...
            var top_count = 0;
            var topfields = new Array();
            var s_idx = new Array();
            var s_title = new Array();
            var s_prev = "";
            var s_count = 0;
            for (var i = 0; i < fields.length; i++) {
                if (fields[i].length == 7) {
                    // store top FAQ
                    topfields[top_count] = fields[i];
                    top_count++;
                }
                // sections info
                var s_current = fields[i][1].join() + fields[i][1].join();
                if (s_current != s_prev) {
                    // new section
                    s_idx[s_count] = fields[i][0][1];
                    s_title[s_count] = fields[i][1][1];
                    s_count++;
                }
                s_prev = s_current;
            }

            // append first sections column
            var oUL = document.createElement("ul");
            oUL.setAttribute("className", "column");
            var i = 0;
            while (2 * i < s_count) {
                var oLI = document.createElement("li");
                var oRef = document.createElement("a");
                oRef.setAttribute("href", "#faq" + s_idx[i]);
                oRef.innerText = s_title[i];
                oLI.appendChild(oRef);
                oUL.appendChild(oLI);
                i++;
            }
            oFeature.appendChild(oUL);
            // append second sections column
            oUL = document.createElement("ul");
            oUL.setAttribute("className", "column");
            while (i < s_count) {
                oLI = document.createElement("li");
                oRef = document.createElement("a");
                oRef.setAttribute("href", "#faq" + s_idx[i]);
                oRef.innerText = s_title[i];
                oLI.appendChild(oRef);
                oUL.appendChild(oLI);
                i++;
            }
            oFeature.appendChild(oUL);

            // append sections TOC
            oData.appendChild(oFeature);

            // append sections faqlists
            // TODO (performance): incorporate in loop for getting sections info...
            s_prev = "";
            for (i = 0; i < fields.length; i++) {
                s_current = fields[i][1].join() + fields[i][0].join();
                if (s_current != s_prev) {
                    if (s_prev != "") {
                        // end section faqlist
                        oSection.appendChild(oDL);
                        oData.appendChild(oSection);
                    }
                    // append new section
                    var oSection = document.createElement("div");
                    oSection.setAttribute("className", "section inactive");
                    //            oSection.setAttribute("className", "section active");

                    oSection.setAttribute("id", "faq" + fields[i][0][1]);
                    // append new section header
                    oHeader = document.createElement("H3");
                    oHeader.innerHTML = fields[i][1][1];
                    oSection.appendChild(oHeader);
                    // start section faqlist
                    var oDL = document.createElement("dl");
                    oDL.setAttribute("className", "faqlist");
                }
                // append faqs
                var oDT = document.createElement("DT");
                // TODO (robustness): use id's (SectionOrder, QuestionOrder) only for (lexicographical) sorting and enumerate questions automatically...
                var id = fields[i][0][1] + "_" + fields[i][2][1];
                var q = fields[i][2][1] + ". " + fields[i][3][1];
                var a = fields[i][4][1]; //_replaceLinks(fields[i][3][1]);
                oRef = document.createElement("a");
                oRef.setAttribute("href", "#faq" + id);
                oRef.innerText = q;
                oDT.appendChild(oRef);
                oDL.appendChild(oDT);
                var oDD = document.createElement("dd");
                oDD.setAttribute("className", "inactive");
                // oDD.setAttribute("className", "active");
                oDD.setAttribute("id", "faq" + id);
                oDD.innerHTML = a;
                oDL.appendChild(oDD);
                // goto next section
                s_prev = s_current;
            }
            // end last section faqlist
            oSection.appendChild(oDL);
            oData.appendChild(oSection);

            // delete current content from <elt>
            KbWorks.UI._resetcontainer(elt);

            // append DOM content to <elt>
            elt.appendChild(oData);

            //elt.innerHTML = a;
        },
        //end display FAQ
        //
        //Begin function init Faq Needed to toggle subitems.
        initFAQ: function(faqDL) {
            // initializes FAQ toggler
            $(faqDL).each(function() {
                var faq = $(this),
    faqTitlesActive = faq.find('dt.active'),
    faqLinks = faq.find('a'),
    faqDescs = faq.find('dd');

                // hide all FAQ descriptions (DD's)
                faqDescs.addClass('inactive');

                // show DD under .active DT's
                faqTitlesActive.each(function() { $(this).next('dd').removeClass('inactive'); });

                // setup event handler on links in DT
                faqLinks.click(function(evt) {
                    evt.preventDefault();
                    $(this).parent().toggleClass('active');
                    $(this).parent().next('dd').toggleClass('inactive');
                });
            });
            // catch active FAQ ID from URL if any and open it
            if (location.hash) {
                if (location.hash != '#') {
                    var faqTarget = $(location.hash);
                    if (faqTarget && faqTarget.is('dd')) {
                        faqTarget.removeClass('inactive')
                        faqTarget.prev('dt').addClass('active');
                    }
                }
            }
        },
        //end function init Faq Needed to toggle subitems.
        //
        //begin function init sections to toggle subitems
        initSections: function(sectionsDIV) {
            // initializes sections toggler
            $(sectionsDIV).each(function() {
                var sections = $(this),
    sectionTitles = sections.find('li'),
    sectionLinks = sections.find('a'),
    sectionFAQlists = $(this).parent().find('div.section');

                // setup event handler on links in sectionDIV
                sectionLinks.click(function(evt) {
                    evt.preventDefault();
                    sectionTitles.removeClass('active');
                    $(this).parent().toggleClass('active');
                    // hide all section faqlists
                    sectionFAQlists.addClass('inactive');
                    // show active section faqlist
                    var sectionFAQlistsActive = document.getElementById($(this).attr('href').substring($(this).attr('href').indexOf('#') + 1));
                    if (sectionFAQlistsActive) sectionFAQlistsActive.setAttribute("className", "active");
                });
                // catch active section ID from URL if any and open it
                if (location.hash) {
                    if (location.hash != '#') {
                        var s_id = location.hash;
                        if (s_id.indexOf('_') != -1) s_id = s_id.substring(0, s_id.indexOf('_'));
                        // activate section
                        for (var i = 0; i < sectionLinks.length; i++) {
                            if (sectionLinks[i].href.indexOf(s_id) != -1)
                                sectionLinks[i].parentNode.setAttribute('className', 'active');
                            else
                                sectionLinks[i].parentNode.removeAttribute('className');
                        }
                        // hide all section faqlists
                        sectionFAQlists.addClass('inactive');
                        // show active section faqlist
                        var sectionFAQlistsActive = document.getElementById(s_id.substring(1));
                        if (sectionFAQlistsActive) sectionFAQlistsActive.setAttribute('className', 'active');
                    }
                }
            });
        }
        //end function init sections to toggle subitems
        //
    },
    //end className Display
    //
    //Begin className Camlquery
    // KbWorks.camlquerybuilder
    camlquerybuilder:
           {
               //begin function generatequery 
               generatequery: function(filter) {
                   var builder = "";
                   //create vars//
                   this.RenderBeginWhere = "<Query><Where>";
                   this.RenderEndWhere = "</Where></Query>";
                   this.RenderBeginOr = "<Or>";
                   this.RenderEndOr = "</Or>";
                   this.RenderBeginAnd = "<And>";
                   this.RenderEndAnd = "</And>";
                   this.RenderBeginOrderBy = "<OrderBy>";
                   this.RenderEndOrderBy = "</OrderBy>";

                   builder = KbWorks.camlquerybuilder._renderfilterfields(filter);
                   return builder;
               },
               //end function generatequery
               //
               //begin function _renderfilterfields
               /// <summary>
               /// Renders all FilterFields in the Filter collection to CAML
               /// </summary>        
               _renderfilterfields: function(Filters) {
                   var builder = "";

                   var filter = new Array;

                   if (Filters.length != 0) {
                       // Add <Where> tag
                       builder += this.RenderBeginWhere;

                       //First create all the and tags but hte last one
                       for (var i = 0; i < (Filters.length - 1); i++) {
                           builder += this.RenderBeginAnd;
                       }

                       // Add <And> tag of there are more fields
                       for (var i = 0; i < Filters.length; i++) {
                           // Always place the most inner 2 first fields in one
                           //AND tag, otherwise query will crash
                           if (i == 0 && Filters.length > 1) {
                               filter = Filters[0];
                               builder += KbWorks.camlquerybuilder._renderfilterfield(filter);

                               filter = Filters[1];
                               builder += KbWorks.camlquerybuilder._renderfilterfield(filter);

                               builder += this.RenderEndAnd;

                               //if only 2 fields only one AND tag required so exit for
                               if (Filters.length == 2) {
                                   break;
                               }

                               i = 2;
                           }

                           filter = Filters[i];
                           builder += KbWorks.camlquerybuilder._renderfilterfield(filter);

                           //only render and if more than one filter
                           if (Filters.length > 1) {
                               builder += this.RenderEndAnd;
                           }
                       }

                       // Add </Where> tag
                       builder += this.RenderEndWhere;
                   }
                   return builder;
               },
               //end function _renderfilterfields
               //
               //begin function _renderfilterfield
               /// <summary>
               /// Renders an FilterField to its corresponding CAML
               /// </summary>
               _renderfilterfield: function(field) {
                   if (field == null)
                       throw new ArgumentNullException("field");

                   // Get the CAML of the field's field value operator.
                   var fieldValueOperator = KbWorks.camlquerybuilder._getfieldvalueoperator(field[3]);

                   var fieldRefWithValue = KbWorks.camlquerybuilder._renderfieldrefwithvalue(field[0], field[1], field[2]);
                   var alternateFieldRefWithValue = "";

                   if (field[4] != null) {
                       var StringBuilder = "";
                       for (var i = 0; i < field[4].length; i++) {
                           alternateFieldRefWithValue = KbWorks.camlquerybuilder._renderfieldrefwithvalue(field[0], field[1], field[4][i]);



                           // Add the <OR> and alternate fieldref / value tags if there is an alternate value
                           if (alternateFieldRefWithValue != "") {
                               // Add  <OR>
                               StringBuilder += this.RenderBeginOr;

                               // Add the field value operator begin tag
                               StringBuilder += fieldValueOperator[0];

                               // Add the fieldref with value tag
                               StringBuilder += alternateFieldRefWithValue;

                               // Add the field value operator end tag
                               StringBuilder += fieldValueOperator[1];
                           }
                       }
                   }
                   // Add the field value operator begin tag
                   StringBuilder += fieldValueOperator[0];

                   // Add the fieldref with value tags
                   StringBuilder += fieldRefWithValue;

                   // Add the field value operator end tag
                   StringBuilder += fieldValueOperator[1];

                   // Add the </OR> tag if there is an alternate value
                   if (alternateFieldRefWithValue != "")
                       for (var i = 0; i < field[4].length; i++) {
                       StringBuilder += this.RenderEndOr;
                   }
                   return StringBuilder;
               },
               //end function _renderfilterfield
               //
               //begin function _getfieldvalueoperator
               /// <summary>
               /// Generates the FieldRef with value syntax
               /// </summary>
               _renderfieldrefwithvalue: function(fieldName, fieldDataType, fieldValue) {
                   if (fieldValue == null)
                       throw new ArgumentNullException("fieldValue");
                   if (fieldName == null)
                       throw new ArgumentNullException("fieldName");
                   if (fieldDataType == null)
                       throw new ArgumentNullException("fieldDataType");

                   //    var valueType = GetValueTypeFromDataType(fieldDataType);

                   var stringbuilder = "";
                   stringbuilder += "<FieldRef Name='";
                   stringbuilder += fieldName;
                   stringbuilder += "'/>";
                   stringbuilder += "<Value Type='";
                   stringbuilder += fieldDataType;
                   stringbuilder += "'>";
                   stringbuilder += fieldValue;
                   stringbuilder += "</Value>";

                   return stringbuilder;
               },
               //end function _getfieldvalueoperator
               //
               //begin function _getfieldvalueoperator
               /// <summary>
               /// Returns the FieldValueOperator in CAML.
               /// </summary>
               _getfieldvalueoperator: function(Operator) {
                   if (Operator == "")
                       throw new ArgumentNullException("Operator");

                   var tags = new Array();
                   switch (Operator) {
                       case "BeginsWith":
                           tags[0] = "<BeginsWith>";
                           tags[1] = "</BeginsWith>";
                           break;
                       case "Contains":
                           tags[0] = "<Contains>";
                           tags[1] = "</Contains>";
                           break;
                       case "EqualTo":
                           tags[0] = "<Eq>";
                           tags[1] = "</Eq>";
                           break;
                       case "GreaterThan":
                           tags[0] = "<Gt>";
                           tags[1] = "</Gt>";
                           break;
                       case "GreaterThanOrEqualTo":
                           tags[0] = "<Geq>";
                           tags[1] = "</Geq>";
                           break;
                       case "LessThan":
                           tags[0] = "<Lt>";
                           tags[1] = "</Lt>";
                           break;
                       case "LessThanOrEqualTo":
                           tags[0] = "<Leq>";
                           tags[1] = "</Leq>";
                           break;
                   }
                   return tags;
               },
               //end function _getfieldvalueoperator
               //
               //begin function generateviewfields
               //generate xml to view the fields
               generateviewfields: function(viewfields) {
                   var builder = "";
                   if (viewfields != null) {
                       builder = "<ViewFields>"
                   }
                   for (var i = 0; i < viewfields.length; i++) {
                       builder += "<FieldRef Name='";
                       if (viewfields[i][3] != null) {
                           builder += viewfields[i][3];
                       }
                       else {
                           builder += viewfields[i][0];
                       }
                       builder += "' />";
                   }
                   if (viewfields != null) {
                       builder += "</ViewFields>"
                   }
                   return builder;
               }
               //end function generateviewfields

           }
    //end className Camlquery
};
//end namespace KbWorks